//
//  TWBaseRequestModel.m
//  TWHomework-WeChat
//
//  Created by wzb on 2019/11/12.
//  Copyright © 2019 WZB. All rights reserved.
//

#import "TWBaseRequestModel.h"
#import <objc/runtime.h>
#import <CommonCrypto/CommonDigest.h>
#import <CoreData/CoreData.h>

static NSSet *classes;

@implementation TWBaseRequestModel

#pragma mark - public

+ (instancetype)newWithCaller:(id)caller {
    return [[self alloc] initWithCaller:caller];
}

+ (instancetype)newWithCaller:(id)caller Path:(NSString*)path {
    TWBaseRequestModel* res = [self newWithCaller:caller];
    res.apiUrl = path;
    return res;
}

- (instancetype)initWithCaller:(id)caller {
    if (self = [super init]) {
        self.model = TWRequestModelGet;
        self.caller = caller;
    }
    return self;
}
// 模型转字典
- (NSMutableDictionary *)getParameterDictionary {
    
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    Class c = self.class;
    
    while (c) {
        unsigned count;
        objc_property_t *properties = class_copyPropertyList([c class], &count);
        
        for (int i = 0; i < count; i++) {
            NSString *key = [NSString stringWithUTF8String:property_getName(properties[i])];
            dict[key] = [self valueForKey:key];
        }
        free(properties);
        
        // 获得父类
        c = class_getSuperclass(c);
        
        if ([self __isClassFromFoundation:c]) break;
    }
    return dict;
}

#pragma mark - private
- (BOOL)__isClassFromFoundation:(Class)c
{
    if (c == [NSObject class] || c == [NSManagedObject class]) return YES;
    
    __block BOOL result = NO;
    [[self __foundationClasses] enumerateObjectsUsingBlock:^(Class foundationClass, BOOL *stop) {
        if ([c isSubclassOfClass:foundationClass]) {
            result = YES;
            *stop = YES;
        }
    }];
    return result;
}

- (NSSet *)__foundationClasses
{
    if (classes == nil) {
        // 集合中没有NSObject，因为几乎所有的类都是继承自NSObject，具体是不是NSObject需要特殊判断
        classes = [NSSet setWithObjects:
                              [NSURL class],
                              [NSDate class],
                              [NSValue class],
                              [NSData class],
                              [NSError class],
                              [NSArray class],
                              [NSDictionary class],
                              [NSString class],
                              [NSAttributedString class], nil];
    }
    return classes;
}

@end
